package com.xt.mvcpilot.service.impl;

import java.util.ArrayList;
import java.util.Calendar;
import java.util.Date;
import java.util.LinkedHashMap;
import java.util.List;
import java.util.Set;
import java.util.HashSet;

import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Propagation;
import org.springframework.transaction.annotation.Transactional;

import org.springframework.security.core.userdetails.UserDetails;
import org.springframework.security.core.userdetails.UserDetailsService;
import org.springframework.security.core.userdetails.UsernameNotFoundException;

import com.xt.core.BaseConstants; 
import com.xt.core.exception.ObjectCanNotSaveException; 

import com.xt.mvcpilot.dao.RoleDao;
import com.xt.mvcpilot.dao.PermissionDao;
import com.xt.mvcpilot.dao.UserDao;
import com.xt.mvcpilot.data.Permission;
import com.xt.mvcpilot.data.Role;
import com.xt.mvcpilot.data.User;
import com.xt.mvcpilot.exception.DaoException;
import com.xt.mvcpilot.service.UserService;


/**
 * class for the xtmvcpilot application
 * 
 * hibernate implementation service class to get user information
 * 
 * @author txiao
 * @version Revision: 1.0, Date: 07.06.2011
 *
 */

@Service("userService")
@Transactional(propagation=Propagation.SUPPORTS, readOnly=true)
public class UserServiceImpl extends AppBasicServiceImpl<User, Long> implements UserService, UserDetailsService{ 
	
	private UserDao userDao;
	@Autowired
	private RoleDao roleDao;
	@Autowired
	private PermissionDao permissionDao;
	
	
	@Autowired
	public UserServiceImpl(UserDao userDao) {
		super(userDao);
		this.userDao = userDao;
	}

	public UserDao getUserDao() {
		return userDao;
	}

	//the business logics
	public Set<Role> getAllRoles() {
		return new HashSet<Role>(roleDao.getAll());
	}

	public Role getRole(Long id){
		return roleDao.get(id);
	}
	
	@Transactional(propagation=Propagation.REQUIRES_NEW, readOnly=false)
	public void saveRole(Role role) throws DaoException {
		try{
			//roleDao.saveorupdate(role);
			roleDao.save(role);
		}catch(Exception oe){
			throw new DaoException("role.error.cannotsave: " + oe.getMessage());
		}
	}
	
	@Transactional(propagation=Propagation.REQUIRES_NEW, readOnly=false)
	public void deleteRoleById(Long id) throws DaoException{
		try{
			roleDao.remove(id);
		}catch(Exception e){
			throw new DaoException("role.error.cannotdelete");
		}
	}
	
	@Transactional(propagation=Propagation.REQUIRED, readOnly=false)
	public Role addPermissionToRole(Role role, Permission permission)
			throws DaoException {
		role.addPerm(permission);
		try{
			roleDao.saveorupdate(role);
		}catch(ObjectCanNotSaveException oe){
			throw new DaoException("roleservice.cannotsave");
		}
		return role;
	}

	@Transactional(propagation=Propagation.REQUIRED, readOnly=false)
	public Role removePermissionFromRole(Role role, Permission permission)
			throws DaoException {
		
		role.deletePerm(permission);
		try{
			//roleDao.saveorupdate(role);
			roleDao.save(role);
		}catch(Exception oe){
			throw new DaoException("roleservice.cannotsave");
		}
		
		return role;
	}

	@Transactional(propagation=Propagation.REQUIRED, readOnly=false)
	public void deleteRole(Role role) throws DaoException {
		roleDao.delete(role);
	}

	public Set<Permission> getAllPermissons() throws DaoException {
		return new HashSet<Permission>(permissionDao.getAll());
	}
	
	public Permission getPermission(Long id){
		return permissionDao.get(id);
	}

	@Transactional(propagation=Propagation.REQUIRES_NEW, readOnly=false)
	public void savePermission(Permission permission) throws DaoException {
		try{
//			Long id = permission.getId(); 
//			if(id==null)
//				permissionDao.save(permission);
//			else
//				permissionDao.saveorupdate(permission);
			permissionDao.save(permission);
		}catch(Exception oe){
			throw new DaoException("permissionservice.cannotsave");
		}
	}

	@Transactional(propagation=Propagation.REQUIRED, readOnly=false)
	public void deletePermission(Permission permission) throws DaoException {
		permissionDao.delete(permission);
	}	
	
	@Transactional(propagation=Propagation.REQUIRED, readOnly=false)
	public void deletePermissionById(Long id) throws DaoException{
		permissionDao.remove(id);
	}
	
	//getters and setters
	public void setUserDao(UserDao userDao) {
		this.userDao = userDao;
	}

	public void setRoleDao(RoleDao roleDao) {
		this.roleDao = roleDao;
	}

	public void setPermissionDao(PermissionDao permissionDao) {
		this.permissionDao = permissionDao;
	}

	/**
	 * Method from Spring-Security
	 * 
	 */
	public UserDetails loadUserByUsername(String userName)
		throws UsernameNotFoundException {
		User user = userDao.getUserByUserName(userName);
		if(user == null)
			throw new UsernameNotFoundException("User with login " + userName + "  has not been found.");
		return user;
	}


	
}
